package com.eportal.aop;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.eportal.annotation.FieldComment;
import com.eportal.domain.Sysopt;
import com.eportal.service.SystemLogService;


/**
 * ***********************************************
 *
 * @file: LogAspect.java
 * @class: LogAspect
 * @description:
 * @author: dyl
 * @since: 2008-5-10-15:45:05
 * @history:
 */
@Component
@Aspect
// 切面定义标签
public class LogAspect {

    private Object sessionValue; // 当前操作员基本信息

    @Autowired
    private SystemLogService systemLogService;

    @Pointcut("execution(* *.*.*.service..*.save*(..)) || execution(* *.*.*.service..*.*update*(..)) "
            + "|| execution(* *.*.*.service..*.del*(..))")
    public void insertPointcut() {
    }

    public void setSessionValue(Sysopt sessionValue) {
        this.sessionValue = sessionValue;
    }

    public Object getSessionValue() {
        return sessionValue;
    }

    /*
	 * 配置前置通知,使用在方法aspect()上注册的切入点
	 * 同时接受JoinPoint切入点对象,可以没有该参数
	 */
//	@Before("aspect()")
//	public void before(JoinPoint joinPoint){
//			System.out.println("before " + joinPoint);
//	}
//    
    @AfterReturning("insertPointcut()")
    public void insertLogInfo(JoinPoint joinPoint) {
    	System.out.println(joinPoint);
        /*if (joinPoint.getTarget().getClass().toString().indexOf("SystemLog") > -1) {
            return;
        }
        sessionValue = (Object) SystemContext.getWebSession().getAttribute("admin");
        String uname = "";
        if (sessionValue instanceof Sysuser) {
            uname = ((Sysuser) sessionValue).getLoginname();
        } else if (sessionValue instanceof Tagent) {
            uname = ((Tagent) sessionValue).getAgtloguser();
        }
        SystemLog systemLog = new SystemLog();
        if (null != sessionValue) {
            systemLog.setUsername(uname);
            systemLog.setIpAdd(Tools.getIpAddr(SystemContext.getWebRequest()));
        }
        // 获取拦截的方法名
        String method = joinPoint.getSignature().getName();
        systemLog.setOperType(getOperType(joinPoint.getSignature().getName()));
        Object objArgsObject = joinPoint.getArgs()[0];// 取得第一个参数对象
        int postion = method.indexOf("del");
        if(postion > -1){
            systemLog.setObjectid(String.valueOf(objArgsObject));
            systemLog.setDotime(new Date());
            systemLog.setSlogType("操作日志");
            systemLog.setOperObject(method.substring(postion+3).toUpperCase());
        }else{
            Map<String, Object> result = null;
            try {
                result = getObjectValue(objArgsObject);
                systemLog.setObjectid(String.valueOf(result.get("sid")));
                systemLog.setSlogComment(JSONObject.fromObject(result).toString());
                systemLog.setOperObject(HibernateConfigurationHelper.getTableNameByClass((objArgsObject.getClass().getName().toString()).split("\\$")[0]));
                systemLog.setDotime(new Date());
                systemLog.setSlogType("操作日志");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            systemLogService.saveOrUpdateSystemLog(systemLog);
        } catch (Exception e) {
            e.printStackTrace();
        }*/
    }

    /**
     * 判断这个方法的操作类型
     *
     * @param method 要判断的方法名称
     * @return String 返回操作类型
     */
    private String getOperType(String method) {
        String operType = "";
        if (method.indexOf("saveOrUpdate") > -1) {
            operType = "新增或更新";
        } else if (method.indexOf("save") > -1) {
            operType = "新增";
        } else if (method.indexOf("update") > -1) {
            operType = "更新";
        } else if (method.indexOf("remove") > -1
                || method.indexOf("del") > -1) {
            operType = "删除";
        }
        return operType;
    }


    public static Map<String, Object> getObjectValue(Object object) throws Exception {

        Map<String, Object> reslut = new HashMap<String, Object>();

        if (object != null) {
            Class<?> clz = object.getClass();
            Field[] fields = clz.getDeclaredFields();

            for (Field field : fields) {
                if (field.getGenericType().toString().equals(
                        "class java.lang.String")) {
                    Method m = object.getClass().getMethod(
                            "get" + getMethodName(field.getName()));

                    if (m.isAnnotationPresent(FieldComment.class)) {
                        String FiledComment = m.getAnnotation(FieldComment.class).value();
                        if (StringUtils.isNotEmpty(FiledComment)) {
                            String val = (String) m.invoke(object);// 调用getter方法获取属性值
                            reslut.put(FiledComment, val);
                        }
                    }
                }
                if (field.getGenericType().toString().equals(
                        "class java.lang.Integer")) {
                    Method m = object.getClass().getMethod(
                            "get" + getMethodName(field.getName()));
                    if (m.isAnnotationPresent(FieldComment.class)) {
                        String FiledComment = m.getAnnotation(FieldComment.class).value();
                        if (StringUtils.isNotEmpty(FiledComment)) {
                            Integer val = (Integer) m.invoke(object);
                            reslut.put(field.getName(), val);
                        }
                    }
                }
                // 如果类型是Double
                if (field.getGenericType().toString().equals(
                        "class java.lang.Double")) {
                    Method m = object.getClass().getMethod(
                            "get" + getMethodName(field.getName()));
                    if (m.isAnnotationPresent(FieldComment.class)) {
                        String FiledComment = m.getAnnotation(FieldComment.class).value();
                        if (StringUtils.isNotEmpty(FiledComment)) {
                            Double val = (Double) m.invoke(object);
                            reslut.put(field.getName(), val);
                        }
                    }
                }
                // 如果类型是Boolean 是封装类
                if (field.getGenericType().toString().equals(
                        "class java.lang.Boolean")) {
                    Method m = object.getClass().getMethod(
                            field.getName());
                    if (m.isAnnotationPresent(FieldComment.class)) {
                        String FiledComment = m.getAnnotation(FieldComment.class).value();
                        if (StringUtils.isNotEmpty(FiledComment)) {
                            Boolean val = (Boolean) m.invoke(object);
                            reslut.put(field.getName(), val);
                        }
                    }
                }

                if (field.getGenericType().toString().equals("boolean")) {
                    Method m = object.getClass().getMethod(
                            field.getName());
                    if (m.isAnnotationPresent(FieldComment.class)) {
                        String FiledComment = m.getAnnotation(FieldComment.class).value();
                        if (StringUtils.isNotEmpty(FiledComment)) {
                            Boolean val = (Boolean) m.invoke(object);
                            reslut.put(field.getName(), val);
                        }
                    }
                }
                if (field.getGenericType().toString().equals(
                        "long")) {
                    Method m = object.getClass().getMethod(
                            "get" + getMethodName(field.getName()));
                    if (m.isAnnotationPresent(FieldComment.class)) {
                        String FiledComment = m.getAnnotation(FieldComment.class).value();
                        if (StringUtils.isNotEmpty(FiledComment)) {
                            long val = (Long) m.invoke(object);
                            reslut.put(field.getName(), val);
                        }
                    }
                }
                if (field.getGenericType().toString().equals(
                        "class java.util.Date")) {
                    Method m = object.getClass().getMethod(
                            "get" + getMethodName(field.getName()));
                    if (m.isAnnotationPresent(FieldComment.class)) {
                        String FiledComment = m.getAnnotation(FieldComment.class).value();
                        if (StringUtils.isNotEmpty(FiledComment)) {
                            Date val = (Date) m.invoke(object);
                            reslut.put(field.getName(), val);
                        }
                    }
                }

                if (field.getGenericType().toString().equals(
                        "class java.lang.Short")) {
                    Method m = object.getClass().getMethod(
                            "get" + getMethodName(field.getName()));
                    if (m.isAnnotationPresent(FieldComment.class)) {
                        String FiledComment = m.getAnnotation(FieldComment.class).value();
                        if (StringUtils.isNotEmpty(FiledComment)) {
                            Short val = (Short) m.invoke(object);
                            reslut.put(field.getName(), val);
                        }
                    }
                }
            }
        }
        return reslut;
    }

    // 把一个字符串的第一个字母大写、效率是最高的、
    private static String getMethodName(String fildeName) throws Exception {
        byte[] items = fildeName.getBytes();
        items[0] = (byte) ((char) items[0] - 'a' + 'A');
        return new String(items);
    }
}

